<?php

	namespace Phptricks\system\library\loaders;

/*
	 * this is class
	 */
	use Phptricks\system\core\library\library;
	use Phptricks\system\library\PhptricksExceptions\PhptricksExceptions as Exc;

	class loader implements library{

		public $_registerDirs = array();
		public $_registerModels = array();
		public $_registerLibrary = array();
		public $_registerControllers = array();
		public $_registerConfig = array();
		public $_registerLanguage = array();
		public $_registerView = array();
		private $_currnet_file;
		public $_error_file_load = array();
		public $_loaded_files = array();
		public $view_load_files = false;
		private static $_instance = null;

		public function __construct(){
			spl_autoload_register(array($this, 'load'));
			set_include_path(\DOCUMENT_ROOT);
		}

		public static function &getinstance(){
			if (self::$_instance === null) {
				self::$_instance = new \Phptricks\system\library\loaders\loader();
			}
			return self::$_instance;
		}

		/**
		 * @param $dirs <p>
		 * The input array.
		 * </p>
		 * @return array register dirs to your mvc.
		 */
		public function registerDirs($dirs = array()){
			if (isset($dirs) && \is_array($dirs) && \count($dirs) > 0) {
				foreach ($dirs as $key => $val) {
					if (!in_array($val, $this->_registerDirs)) {
						$this->_registerDirs[] = $val;
					}
				}
				unset($dirs);
				sort($this->_registerDirs);
			} else {
				throw new Exc('this <strong>$dirs</strong> is must be array not ' . \strtolower(\gettype($dirs)));
			}
			return $this;
		}

		/**
		 * @param $dirs <p>
		 * The input array.
		 * </p>
		 * @return array register dirs to your mvc.
		 * @link htttp://google.com
		 */
		public function setpath($dirs = array()){
			if (\in_array('config', \array_keys($dirs))) {
				$this->_registerConfig = $dirs['config'];
				unset($dirs['config']);
			}
			if (\in_array('controllers', \array_keys($dirs))) {
				$this->_registerControllers = $dirs['controllers'];
				unset($dirs['controllers']);
			}
			if (\in_array('library', \array_keys($dirs))) {
				$this->_registerLibrary = $dirs['library'];
				unset($dirs['library']);
			}
			if (\in_array('language', \array_keys($dirs))) {
				$this->_registerLanguage = $dirs['language'];
				unset($dirs['language']);
			}
			if (\in_array('models', \array_keys($dirs))) {
				$this->_registerModels = $dirs['models'];
				unset($dirs['models']);
			}
			if (\in_array('view', \array_keys($dirs))) {
				$this->_registerView = $dirs['view'];
				unset($dirs['view']);
			}
			$this->_registerDirs = $dirs;
			unset($dirs);
//			return $this;
		}

		/**
		 * @param String $class
		 */
		public function load($class){
//			echo $class . "\n<br>\n";
			$include_path = $class;
			if (count(explode('\\', $class)) > 1) {
				$explode_string = explode('\\', $class);
				unset($explode_string[0]);
				$include_path = implode(\DS, $explode_string);
			}
			if (empty($include_path)) {
				die("file is is is " . $include_path . " ");
			}
			$check_file = implode(\DS, array_slice(explode('/', $include_path), 0, (count(explode('/', $include_path)) - 1))) . \EXT;
			if ($this->_getfile($check_file) == true) {
				$file_name = $check_file;
			} else {
				$file_name = $include_path . \EXT;
			}
			if ($this->_getfile($file_name) == true) {
				require_once ($this->_currnet_file);
				$this->_loaded_files[] = $this->_currnet_file;
				return true;
			} else {
				$this->_error_file_load[] = $file_name;
				return false;
			}
		}

		public function _autoload($path, $array_files){
			if (!isset($path) || empty($path)) {
				throw new Exc("You must enter a path in param \$path");
			}
			if (!isset($array_files) || empty($array_files)) {
				throw new Exc("You must enter a files name in param \$array_files");
			}
			$array_path = '';
			if (\is_array($path)) {
				$array_path = $path;
				foreach ($array_path as $key => $path_val) {
					if (\is_array($array_files) && \count($array_files) > 0) {
						foreach ($array_files as $key => $file) {
							$file_path = $path_val . $file . \DS . $file . \EXT;
							if (\file_exists($file_path)) {
								$this->_loaded_files[] = $file_path;
								require_once ($file_path);
							} else {
								$this->_error_file_load[] = 'this file : ' . $file_path . ' not found in ' . $path_val . ' please check your file path';
							}
						}
					} else {
						$file_path = $path_val . $array_files . \DS . $array_files . \EXT;
						if (\file_exists($file_path)) {
							$this->_loaded_files[] = $file_path;
							require_once ($file_path);
						} else {
							$this->_error_file_load[] = 'this file : ' . $file_path . ' not found in <strong>' . $path_val . '</strong> please check your fiile path';
						}
					}
				}
			} else {
				if (\is_array($array_files) && \count($array_files) > 0) {
					foreach ($array_files as $key => $file) {
						$file_path = $path . $file . \DS . $file . \EXT;
						if (\file_exists($file_path)) {
							$this->_loaded_files[] = $file_path;
							require_once ($file_path);
						} else if (\file_exists($path . $array_files . \EXT)) {
							$file_path = $path . $array_files . \EXT;
							$this->_loaded_files[] = $file_path;
							require_once ($file_path);
						} else {
							$this->_error_file_load[] = 'this file : ' . $file_path . ' not found in ' . $path . ' please check your fiile path';
						}
					}
				} else {
					$file_path = $path . $array_files . \DS . $array_files . \EXT;
					if (\file_exists($file_path)) {
						$this->_loaded_files[] = $file_path;
						require_once ($file_path);
					} else if (\file_exists($path . $array_files . \EXT)) {
						$file_path = $path . $array_files . \EXT;
						$this->_loaded_files[] = $file_path;
						require_once ($file_path);
					} else {
						$this->_error_file_load[] = 'this file : ' . $file_path . ' not found in <strong>' . $path . '</strong> please check your fiile path';
					}
				}
			}
			if (count($this->_error_file_load) > 0) {
				throw new Exc("files not load :\n\t\t" . implode("\n\t\t", $this->_error_file_load));
			}
			return true;
		}

		public function _getfile($file){
			if ($this->_is_loaded($file) == false) {
				if (\file_exists($file)) {
					$this->_currnet_file = $file;
					return true;
				} else if (count($this->_registerDirs) > 0) {
					foreach ($this->_registerDirs as $key => $val) {
						if (\file_exists($val . $file)) {
							$this->_currnet_file = $val . $file;
							return true;
						}
					}
				}
			}
			return false;
		}

		public function _is_loaded($filename){
			$array_file = \get_included_files();
			foreach ($array_file as $key => $val) {
				if (\strpos($val, $filename)) {
					return true;
				}
			}
			return false;
		}

		public static function load_dir($dir_path){
			if (!\is_dir($dir_path)) {
				throw new Exc('this is not dir:' . $dir_path);
			}
			$dir_path = \rtrim($dir_path, DS) . "/*";
			$files = glob($dir_path);
			if (count($files) > 0) {
				foreach ($files as $key => $val) {
					if (preg_match('/\//iUs', $val) == true) {
						$ex_val = explode(DS, $val);
						$file = \rtrim($val, DS) . DS . end($ex_val) . EXT;
						if (\file_exists($file)) {
							require_once ($file);
						}
					}
				}
			}
			return true;
		}

		/**
		 * @param String $model_name 
		 */
		public function _getfiles($dir){

			if ($dirs = dir($dir)) {
				$files = glob($dir . "*" . \EXT);
				$files = str_replace(array($dir, \EXT), "", $files);
			}
			return $files;
		}

		/**
		 * @param String $config 
		 */
		public function _config($config){
			foreach ($this->_registerConfig as $key => $val) {
				$file = $val . $config . \EXT;
				if ($this->_is_loaded($file) == false) {
					if (\file_exists($file)) {
						$this->_currnet_file = $file;
						$this->_loaded_files[] = $this->_currnet_file;
						require_once ($this->_currnet_file);
					}
					return $config;
				}
			}
			return false;
		}

		/**
		 * @param String $model_name 
		 */
		public function _model($model_name){
			$model_path = '';
			foreach ($this->_registerModels as $key => $val) {
				$model_path = $val . $model_name . \DS . $model_name . \EXT;
				if (\file_exists($model_path)) {
					$this->_currnet_file = $model_path;
				}
			}
			if (!empty($model_path)) {
				if ($this->_is_loaded($model_path) == false) {
					require ($this->_currnet_file);
					$this->_loaded_files[] = $this->_currnet_file;
				}
				return true;
			} else {
				throw new Exc("files not load :\n\t\t" . $model_name);
			}
		}

		public function _Library($library_name){
			$library_path = '';
			foreach ($this->_registerLibrary as $key => $val) {
				$library_path = $val . $library_name . \DS . $library_name . \EXT;
				if (\file_exists($library_path)) {
					$this->_currnet_file = $library_path;
				}
			}
			if (!empty($library_path)) {
				if ($this->_is_loaded($this->_currnet_file) == false) {
					require ($this->_currnet_file);
					$this->_loaded_files[] = $this->_currnet_file;
				}
				return true;
			} else {
				throw new Exc("files not load :\n\t\t" . $library_name);
			}
		}

		/**
		 * @param String|Array $langname 
		 */
		public function _Language($langname){
			if (!isset($langname) && empty($langname)) {
				throw new Exc("You must enter a path in param \$langname");
			}
			$array_lang_retrun = array();
			if (\is_array($langname) && \count($langname) > 0) {
				foreach ($langname as $lang_key => $lang_value) {
					foreach ($this->_registerLanguage as $key => $val) {
						$file = $val . $lang_value . \EXT;
						if (\file_exists($file)) {
							$this->_currnet_file = $file;
							require ($this->_currnet_file);
							$array_lang_retrun = \array_merge($array_lang_retrun, $lang);
						}
					}
				}
			} else {
				foreach ($this->_registerLanguage as $key => $val) {
					$file = $val . $langname . \EXT;
					if (\file_exists($file)) {
						$this->_currnet_file = $file;
						require ($this->_currnet_file);
						$array_lang_retrun = \array_merge($array_lang_retrun, $lang);
					}
				}
			}
			return $array_lang_retrun;
		}

		public function __destruct(){
			if ($this->view_load_files) {
				if (\count($this->_error_file_load) > 0) {
					echo "Error File Load";
					\pr($this->_error_file_load);
				}
				echo "<br>\n File Load";
//				\sort($this->_loaded_files);
				\pr($this->_loaded_files);
			}
		}

	}

?>